package com.zxl.job;


import com.xxl.job.core.biz.model.ReturnT;
import com.xxl.job.core.handler.IJobHandler;
import com.xxl.job.core.handler.annotation.JobHandler;
import com.zxl.entities.MmMessage;
import com.zxl.model.dto.MmMessageDto;
import com.zxl.service.MmMessageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.util.List;


/**
 * 任务Handler示例（Bean模式）
 * <p>
 * 开发步骤：
 * 1、继承"IJobHandler"：“com.xxl.job.core.handler.IJobHandler”；
 * 2、注册到Spring容器：添加“@Component”注解，被Spring容器扫描为Bean实例；
 * 3、注册到执行器工厂：添加“@JobHandler(value="自定义jobhandler名称")”注解，
 * 注解value值对应的是调度中心新建任务的JobHandler属性的值。
 * 4、执行日志：需要通过 "XxlJobLogger.log" 打印执行日志；
 */
@JobHandler(value = "deliverMsgJobHandler")
@Component
public class DeliverMsgJobHandler extends IJobHandler {
    @Resource
    private MmMessageService msgService;
    @Resource
    private LoadBalancerClient loadBalancerClient;//ribbon 负载均衡客户端
    //过期时间 单位分钟
    private static final int VERDUE_TIME = 1;
    private static final Logger LOGGER = LoggerFactory.getLogger(DeliverMsgJobHandler.class);
    @Override
    public ReturnT<String> execute(String param) throws Exception {
        LOGGER.info("进入投递定时任务..........................");
        this.processMsg();
        return SUCCESS;
    }

    public void processMsg() {
        //1.定时器轮询过期“待发送”状态的消息（过期消息一般是根据业务规则自行调整，例如 1min）
        List<MmMessage> msgList = this.msgService.selectOverdueMsgByNotSend(VERDUE_TIME);
        for (MmMessage msg : msgList) {
            //2.消息微服务dtx_msg5001向支付微服务dtx_pay4001发起状态查询，并且支付服务返回业务执行状态。
            boolean bo = this.checkMsg(msg);
            //true=已支付成功，把消息改为已发送，并发送消息
            //3.消息服务对消息进行确认：如果业务执行成功，则发送MQ消息并更改消息状态为“已发送”
            //tx_msg表`status`消息状态 0=待发送 1=已发送 '
            if (bo) {
				MmMessageDto msgDTO = new MmMessageDto();
                BeanUtils.copyProperties(msg, msgDTO);
                this.msgService.confirmMsg(msgDTO);
            } else {
                //3.否则删除此条消息确保数据一致性。
                //直接删除消息 or delete字段逻辑删除 or 归档不删除
				MmMessageDto msgDTO = new MmMessageDto();
                msgDTO.setMsgId(msg.getMsgId());
                this.msgService.deleteMsg(msgDTO);
            }
        }
    }

    /**
     * 消息微服务dtx_msg5001向支付微服务dtx_pay4001发起状态查询，并且支付微服务dtx_pay4001返回业务执行状态。
     * 也即，支付微服务dtx_pay4001新建MsgController类提供checkMsg方法专门给定时器结合tx_msg表的
     * `status消息状态 0=待发送 1=已发送 ',来进行回查
     *
     * @param msg
     * @return
     */
    public boolean checkMsg(MmMessage msg) {
        //解析订单号
        String msgid = msg.getMsgId();
        String[] array = msgid.split("-");
        String id = array[1];
        //调接口
        ServiceInstance si = loadBalancerClient.choose(msg.getAppName());
        StringBuffer sb = new StringBuffer();
        sb.append("http://");
        sb.append(si.getHost());
        sb.append(":");
        sb.append(si.getPort());
        sb.append("/checkMsg/");
        sb.append(id);
        LOGGER.info("回调服务地址：{}", sb);
        RestTemplate restTemplate = new RestTemplate();
        return Boolean.TRUE.equals(restTemplate.getForObject(sb.toString(), Boolean.class, "java"));
    }


}
